/**
 * 
 */
package gui.view;

import gui.controller.TrustPanelListener;

import java.awt.Color;
import java.awt.Font;
import java.util.Enumeration;
import java.util.Hashtable;

import javax.swing.BorderFactory;
import javax.swing.GroupLayout;
import javax.swing.JButton;
import javax.swing.JComboBox;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.JTextArea;
import javax.swing.JTextField;
import javax.swing.ScrollPaneConstants;
import javax.swing.GroupLayout.Alignment;
import javax.swing.GroupLayout.ParallelGroup;
import javax.swing.GroupLayout.SequentialGroup;
import javax.swing.border.Border;
import javax.swing.border.TitledBorder;
import javax.swing.table.DefaultTableCellRenderer;
import javax.swing.table.TableColumn;

import massDistribution.MeasuredAttribute;

/**
 * @author Elisa Costante
 * 
 */
public class TrustPanel extends JPanel {

	private static final long serialVersionUID = -1981031404244532051L;

	private JPanel upPanel;
	private JLabel attributeLabel;
	private JComboBox attributeCombo;
	private JButton addAttributeButton;
	private JLabel trustLevelLabel;
	private JLabel trustNameLabel;
	private JTextField trustNameTxtField;
	private JLabel trustValeuLabel;
	private JTextField trustValueTxtField;
	private JButton addTrustClassButton;
	private JTable configurationDbTable;
	private TrustSettingsTableModel tableModel;
	private JScrollPane configurationDbScroll;
	private JButton validateButton;
	private JButton removeColumn;
	private JButton removeRow;

	private JTextArea rangeExplanationTxtArea;

	private TrustPanelListener listener;

	private EngineMain frame;

	private JButton loadButton;

	private JButton saveButton;

	public TrustPanel(EngineMain frame) {
		super();
		this.frame = frame;
		initPanel();
	}

	private void initPanel() {
		this.setBackground(CustomizedColor.BACK_GROUND_COLOR);
		listener = new TrustPanelListener(this);

		setUpComponents();
		setUpPanel();
		setMainPanelLayout();

	}

	private void setUpComponents() {
		attributeLabel = new JLabel("Attribute");
		attributeCombo = new JComboBox();
		attributeCombo.setActionCommand("showAttribute");
		attributeCombo.addItem("..select an attribute");
		attributeCombo.addActionListener(listener);
		addAttributesToCombo();

		addAttributeButton = new JButton("Add");
		addAttributeButton.setActionCommand("addattributeButton");
		addAttributeButton.addActionListener(listener);

		trustLevelLabel = new JLabel("Trust Class");

		trustNameLabel = new JLabel("Name");
		trustNameTxtField = new JTextField();
		trustNameTxtField.setToolTipText("Insert the name");

		trustValeuLabel = new JLabel("Value [opt]");
		trustValueTxtField = new JTextField();
		trustValueTxtField.setToolTipText("Insert an Integer or Real value");

		addTrustClassButton = new JButton("Add");
		addTrustClassButton.setActionCommand("addTrustClassClass");
		addTrustClassButton.addActionListener(listener);

		configurationDbScroll = new JScrollPane(getConfigurationDbTable());
		configurationDbScroll
				.setHorizontalScrollBarPolicy(ScrollPaneConstants.HORIZONTAL_SCROLLBAR_AS_NEEDED);
		configurationDbScroll
				.setVerticalScrollBarPolicy(ScrollPaneConstants.VERTICAL_SCROLLBAR_AS_NEEDED);
		getConfigurationDbTable().setFillsViewportHeight(true);

		validateButton = new JButton("Validate");
		validateButton.setActionCommand("validate");
		validateButton.addActionListener(listener);

		removeColumn = new JButton("Remove Column");
		removeColumn.setActionCommand("removeColumn");
		removeColumn.addActionListener(listener);

		removeRow = new JButton("Remove Row");
		removeRow.setActionCommand("removeRow");
		removeRow.addActionListener(listener);

		loadButton = new JButton("Load");
		loadButton.setActionCommand("load");
		loadButton.addActionListener(this.listener);

		saveButton = new JButton("Save");
		saveButton.setActionCommand("save");
		saveButton.addActionListener(this.listener);

	}

	/**
	 * Add all the attributes defined into the AttributesPanel to the list
	 */
	public void addAttributesToCombo() {

		Hashtable<String, MeasuredAttribute> monitoredAttributes = frame
				.getAttributeList();
		if (monitoredAttributes != null) {
			attributeCombo.removeAllItems();
			Enumeration<MeasuredAttribute> attrEnum = monitoredAttributes
					.elements();
			int i = 0;
			while (attrEnum.hasMoreElements()) {
				MeasuredAttribute attribute = attrEnum.nextElement();
				attributeCombo.addItem(attribute.getIdentifier());
				i++;
			}
		}

	}

	public JTable getConfigurationDbTable() {
		if (configurationDbTable == null) {
			tableModel = new TrustSettingsTableModel();
			configurationDbTable = new JTable(tableModel);
			setWeightColumn();
			setAttributeNameColumn();

		}
		return configurationDbTable;
	}

	/**
	 * 
	 */
	private void setAttributeNameColumn() {
		TableColumn attributeNameColumn = configurationDbTable.getColumnModel()
				.getColumn(TrustSettingsTableModel.ATTRIBUTE_NAME_COLUMN);
		attributeNameColumn.setMaxWidth(100);
	}

	/**
	 * 
	 */
	private void setWeightColumn() {
		TableColumn weightColumn = configurationDbTable.getColumnModel()
				.getColumn(TrustSettingsTableModel.WEIGHT_COLUMN);
		weightColumn.setMaxWidth(60);
		DefaultTableCellRenderer renderer = new DefaultTableCellRenderer();
		renderer
				.setToolTipText("Insert the weight. The sum of all weight must be 1.");
		weightColumn.setCellRenderer(renderer);
	}

	/**
	 * 
	 */
	private void setUpPanel() {
		upPanel = new JPanel();
		upPanel.setBackground(CustomizedColor.BACK_GROUND_COLOR);

		setUpPanelLayout();

	}

	/**
	 * 
	 */
	private void setUpPanelLayout() {
		GroupLayout layout = new GroupLayout(upPanel);
		upPanel.setLayout(layout);
		layout.setAutoCreateGaps(true);
		layout.setAutoCreateContainerGaps(true);

		ParallelGroup horizontal = layout.createParallelGroup(Alignment.CENTER);

		// First Line
		SequentialGroup firstLine = layout.createSequentialGroup();
		firstLine.addComponent(attributeLabel, 100, 100, Short.MAX_VALUE);
		firstLine.addComponent(attributeCombo, 150, 150, Short.MAX_VALUE);
		firstLine.addComponent(addAttributeButton, 100, 100, 100);
		horizontal.addGroup(firstLine);

		// Second Line
		SequentialGroup secondLine = layout.createSequentialGroup();
		secondLine.addComponent(trustLevelLabel, 100, 100, Short.MAX_VALUE);

		SequentialGroup trustNameGroup = layout.createSequentialGroup();
		trustNameGroup.addComponent(trustNameLabel, 50, 50, Short.MAX_VALUE);
		trustNameGroup.addComponent(trustNameTxtField, 100, 100,
				Short.MAX_VALUE);
		secondLine.addGroup(trustNameGroup);

		SequentialGroup trustValueGroup = layout.createSequentialGroup();
		trustValueGroup.addComponent(trustValeuLabel, 50, 50, Short.MAX_VALUE);
		trustValueGroup.addComponent(trustValueTxtField, 100, 150,
				Short.MAX_VALUE);
		secondLine.addGroup(trustValueGroup);

		secondLine.addComponent(addTrustClassButton, 100, 100, 100);
		horizontal.addGroup(secondLine);

		// Explanation txtfiled
		horizontal.addComponent(getRangeExplanationTxtArea(), 100, 300,
				Short.MAX_VALUE);

		// Third Line
		horizontal.addComponent(configurationDbScroll, 100, 300,
				Short.MAX_VALUE);
		// Fourth Line
		SequentialGroup fourthLine = layout.createSequentialGroup();
		fourthLine.addComponent(validateButton, 100, 100, 100);
		fourthLine.addComponent(removeColumn, 150, 150, 150);
		fourthLine.addComponent(removeRow, 150, 150, 150);
		fourthLine.addComponent(saveButton, 100, 100, 100);
		fourthLine.addComponent(loadButton, 100, 100, 100);
		horizontal.addGroup(fourthLine);

		// Vertical

		SequentialGroup vertical = layout.createSequentialGroup();

		// First Line
		ParallelGroup firstVerticalLine = layout.createParallelGroup();
		firstVerticalLine.addComponent(attributeLabel, 30, 30, 30);
		firstVerticalLine.addComponent(attributeCombo, 30, 30, 30);
		firstVerticalLine.addComponent(addAttributeButton, 30, 30, 30);
		vertical.addGroup(firstVerticalLine);

		// Second Line
		ParallelGroup secondVerticalLine = layout.createParallelGroup();
		secondVerticalLine.addComponent(trustLevelLabel, 30, 30, 30);

		ParallelGroup trusVerticaltNameGroup = layout.createParallelGroup();
		trusVerticaltNameGroup.addComponent(trustNameLabel, 30, 30, 30);
		trusVerticaltNameGroup.addComponent(trustNameTxtField, 30, 30, 30);
		secondVerticalLine.addGroup(trusVerticaltNameGroup);

		ParallelGroup trustVerticalValueGroup = layout.createParallelGroup();
		trustVerticalValueGroup.addComponent(trustValeuLabel, 30, 30, 30);
		trustVerticalValueGroup.addComponent(trustValueTxtField, 30, 30, 30);
		secondVerticalLine.addGroup(trustVerticalValueGroup);

		secondVerticalLine.addComponent(addTrustClassButton, 30, 30, 30);
		vertical.addGroup(secondVerticalLine);

		// Explanation area
		vertical.addComponent(getRangeExplanationTxtArea(), 50, 50,
				Short.MAX_VALUE);

		vertical.addComponent(configurationDbScroll, 90, 200, Short.MAX_VALUE);

		ParallelGroup fourthLineVertical = layout.createParallelGroup();

		fourthLineVertical.addComponent(validateButton, 30, 30, 30);
		fourthLineVertical.addComponent(removeColumn, 30, 30, 30);
		fourthLineVertical.addComponent(removeRow, 30, 30, 30);
		fourthLineVertical.addComponent(saveButton, 30, 30, 30);
		fourthLineVertical.addComponent(loadButton, 30, 30, 30);
		vertical.addGroup(fourthLineVertical);

		layout.setHorizontalGroup(horizontal);
		layout.setVerticalGroup(vertical);

	}

	/**
	 * 
	 */
	private void setMainPanelLayout() {
		GroupLayout layout = new GroupLayout(this);
		this.setLayout(layout);
		layout.setAutoCreateGaps(true);
		layout.setAutoCreateContainerGaps(true);

		ParallelGroup horizontal = layout.createParallelGroup();

		horizontal.addComponent(upPanel, this.getWidth(), this.getWidth(),
				Short.MAX_VALUE);

		SequentialGroup vertical = layout.createSequentialGroup();

		vertical.addComponent(upPanel, (this.getHeight() / 4) * 3, (this
				.getHeight() / 4) * 3, Short.MAX_VALUE);

		layout.setHorizontalGroup(horizontal);
		layout.setVerticalGroup(vertical);

	}

	/**
	 * @return the addAttributeButton
	 */
	public JButton getAddAttributeButton() {
		return this.addAttributeButton;
	}

	/**
	 * @param addAttributeButton
	 *            the addAttributeButton to set
	 */
	public void setAddAttributeButton(JButton addAttributeButton) {
		this.addAttributeButton = addAttributeButton;
	}

	/**
	 * @return the tableModel
	 */
	public TrustSettingsTableModel getTableModel() {
		return this.tableModel;
	}

	/**
	 * @param tableModel
	 *            the tableModel to set
	 */
	public void setTableModel(TrustSettingsTableModel tableModel) {
		this.tableModel = tableModel;
		this.configurationDbTable.setModel(this.tableModel);
	}

	/**
	 * @return the attributeCombo
	 */
	public JComboBox getAttributeCombo() {
		return this.attributeCombo;
	}

	/**
	 * @return the trustNameTxtField
	 */
	public JTextField getTrustNameTxtField() {
		return this.trustNameTxtField;
	}

	/**
	 * @return the trustValueTxtField
	 */
	public JTextField getTrustValueTxtField() {
		return this.trustValueTxtField;
	}

	/**
	 * @return the frame
	 */
	public EngineMain getFrame() {
		return this.frame;
	}

	/**
	 * @param configurationDbTable
	 *            the configurationDbTable to set
	 */
	public void setConfigurationDbTable(JTable configurationDbTable) {
		this.configurationDbTable = configurationDbTable;
	}

	public JTextArea getRangeExplanationTxtArea() {
		if (rangeExplanationTxtArea == null) {
			rangeExplanationTxtArea = new JTextArea();
			rangeExplanationTxtArea.setFont(new Font("Serif", Font.PLAIN, 12));

			Border border = BorderFactory.createLineBorder(Color.gray);
			border = BorderFactory.createTitledBorder(border,
					"How to use ranges", TitledBorder.CENTER,
					TitledBorder.CENTER);
			rangeExplanationTxtArea.setBorder(border);
			rangeExplanationTxtArea
					.setText("Enter either a sigle range or multiple ranges.\n "
							+ "For Example:\n"
							+ "Sigle Integer range: 2,4\t"
							+ "Multiple Real ranges: -INF,16.50; 22.0,+INF;\t"
							+ "Multiple Discrete range: true;false;unknown\n\n"
							+ "N.B. the value null must be expressed as NOT_MEASURED.\n");

		}
		return rangeExplanationTxtArea;
	}

}
